package com.tz.shop.seckill.task;

/**
 * @author 铁铸
 * @create 2021-07-16 8:35
 */

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tz.shop.model.activity.SeckillGoods;
import com.tz.shop.seckill.mapper.SeckillMapper;
import com.tz.shop.seckill.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * 秒杀商品存入缓存
 */
@Component
public class SeckillTask {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SeckillMapper seckillMapper;


    /**
     * 定时任务
     */
    @Scheduled(cron="0/15 * * * * *")
    public void seckillIntoRedisTask() {
        //计算五个时间段。利用dataUtil工具
        List<Date> dateMenus = DateUtil.getDateMenus();
        //遍历出五个时间段
        for (Date dateMenu : dateMenus) {
            //从数据库查询出对应时间段的商品数据2021-7-16 20:00
            String startTime = DateUtil.data2str(dateMenu, DateUtil.PATTERN_YYYY_MM_DDHHMM);
            //结算时间截至到2021-7-16 22:00
            Date date = DateUtil.addDateHour(dateMenu, 2);
            String endTime = DateUtil.data2str(date, DateUtil.PATTERN_YYYY_MM_DDHHMM);
            //拼接条件
            LambdaQueryWrapper<SeckillGoods> wrapper = new LambdaQueryWrapper<>();
            //审核状态必须是通过的
            wrapper.eq(SeckillGoods::getStatus,"1");
            //剩余库存量必须大于0
            wrapper.gt(SeckillGoods::getStockCount,0);
            //startTime=<开始时间 结束时间<endTime
            wrapper.ge(SeckillGoods::getStartTime,startTime);
            wrapper.le(SeckillGoods::getEndTime,endTime);
            //判断redis中没有这个数据的
            //这个是将时间转换为另一种形式
            String key = DateUtil.data2str(dateMenu, DateUtil.PATTERN_YYYYMMDDHH);
            //得到redis中key值相对应的key值
            Set keys = redisTemplate.boundHashOps("SeckillGoods_" + key).keys();
            //判断
            if (keys!=null && keys.size()>0){
                //这个是判断这些key值是否和getId对应
                wrapper.notIn(SeckillGoods::getId,keys);
            }
            //查询数据库的数据
            List<SeckillGoods> seckillGoods = seckillMapper.selectList(wrapper);
            //存入Redis: SeckillGoods_2021071620
            //这是根据商品的id将每一个数据压入这个商品队列中
            //数量存入库存中
            for (SeckillGoods seckillGood : seckillGoods) {
                redisTemplate.boundHashOps("SeckillGoods_"+key).put(seckillGood.getId(),seckillGood);
                //获取商品数量
                Integer stockCount = seckillGood.getStockCount();
                //构建一个数量长度的数组
                String[] ids = getSeckillGoodsQueue(seckillGood.getId(), stockCount);
                //将数组的每一个元素放入redis的list队列中去
                redisTemplate.boundListOps("seckillGoodsQueue_"+seckillGood.getId()).leftPushAll(ids);
                //库存进行记录
                redisTemplate.boundHashOps("SeckillGoodsStockNum").increment(seckillGood.getId(),stockCount);
            }
        }
    }

    /**
     * 构建商品库存个数长度的数组
     * @param goodsId
     * @param stockCount
     * @return
     */
    private String[] getSeckillGoodsQueue(String goodsId,Integer stockCount){
        //构建一个库存长度的数组
        String[] ids=new String[stockCount];
        //元素填充
        for (Integer i = 0; i < stockCount; i++) {
            ids[i]=goodsId;
        }
        //返回数据
        return ids;
    }
}
